﻿
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Extentions;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using TrainingReminderSystem.Dal;
using TrainingReminderSystem.Model;

namespace TrainingReminderSystem.Bll
{
    /// <summary>
    /// 逻辑层
    /// </summary>
    public partial class SysRolePostBll : PcLoginedBll
    {
        #region 得到角色下拉

        public AjaxResult<dynamic> GetListSelect(IFormCollection form)
        {
            using (var db = Db)
            {
                Expression<Func<SysRolePost, bool>> where = InitSearch<SysRolePost>(form, InitSearchDelegete); //拼接查询条件方法
                var selectID = form["selectIDName"].ExTrim();
                var obj = db.SysRolePost.AsNoTracking();
                bool hasSelectID = false;
                if (!string.IsNullOrEmpty(selectID))
                {
                    if (selectID.IndexOf(',') != -1)
                    {
                        var selectIDList = selectID.ExToSplitList();
                        if (selectIDList.Count > 0)
                        {
                            hasSelectID = true;
                            obj = obj.OrderByDescending(m => selectIDList.Contains(m.SysRolePostID))
                                .ThenByDescending(m => m.SysRolePostID);
                        }
                    }
                    else
                    {
                        var selectIDInt = selectID.ExToInt32();
                        if (selectIDInt > 0)
                        {
                            hasSelectID = true;
                            obj = obj.OrderByDescending(m => selectIDInt == m.SysRolePostID)
                                .ThenByDescending(m => m.SysRolePostID);
                        }
                    }
                    if (hasSelectID == false)
                    {
                        where = where.ExAnd(m => m.SysRolePostName.Contains(selectID) || m.PY.Contains(selectID));
                    }
                }
                if (hasSelectID == false)
                {
                    obj = obj.OrderByDescending(m => m.SysRolePostID);
                    //where = where.ExAnd(m => m.EnumStatus == EnumStatus.启用);
                }
                var result = new AjaxResult<dynamic>() { Success = true };
                var list = obj.Where(where).Take(DefaultSize);
                var tempList = list.Select(m => new
                {
                    m.SysRolePostID,
                    m.SysRolePostName,
                    m.SysStore.SysStoreName
                });
                result.Result = tempList.ToList();
                return result;
            }
        }

        #endregion

        #region 权限集合

        private static readonly object Sync = new object();

        /// <summary>
        /// 每个数据库缓存的不一样
        /// </summary>
        private static string cacheKey { get; } = "SysPowerCacheKey";

        /// <summary>
        /// 所有权限,包含替换权限
        /// </summary>
        private static List<SysPower> GetAllSysPower(DbEntities db)
        {
            var rights = CacheHelper.GetCache(cacheKey) as List<SysPower>;
            if (rights != null && rights.Count > 0)
            {
                return rights;
            }
            List<SysPower> allList = db.SysPower.AsNoTracking().ToList();

            #region 替换权限

            ////替换权限
            //List<SysPowerReplace> replaceList = db.SysPowerReplace.Include("QB_ReplaceMenuButton").ToList();
            //List<SysPower> allNeedReplace = allList.Where(m => replaceList.Any(n => m.SysPowerID == n.SysPowerID)).ToList();
            ////移除掉多余的
            //foreach (var item in allNeedReplace)
            //{
            //    var sonAllNeedReplace = allList.Where(m => m.ParentID == item.SysPowerID).ToList();
            //    foreach (var sonItem in sonAllNeedReplace)
            //    {
            //        var sonSonAllNeedReplace = allList.Where(m => m.ParentID == sonItem.SysPowerID).ToList();
            //        foreach (var sonSonItem in sonSonAllNeedReplace)
            //        {
            //            var sonSonSonAllNeedReplace = allList.Where(m => m.ParentID == sonSonItem.SysPowerID).ToList();
            //            allList = allList.Where(m => !sonSonSonAllNeedReplace.Contains(m)).ToList();
            //        }
            //        allList = allList.Where(m => !sonSonAllNeedReplace.Contains(m)).ToList();
            //    }

            //    allList = allList.Where(m => !sonAllNeedReplace.Contains(m)).ToList();
            //    allList.Remove(item);
            //}

            //foreach (SysPowerReplace item in replaceList)
            //{
            //    var newOne = new SysPower();
            //    newOne.ExCopyFrom(item);
            //    newOne.SysPower = new List<SysPower>();
            //    foreach (var replaceItem in item.QB_ReplaceMenuButton)
            //    {
            //        var newMenuButton = new SysPower();
            //        newMenuButton.ExCopyFrom(replaceItem);
            //        newMenuButton.SysPower = newOne;
            //        newOne.SysPower.Add(newMenuButton);
            //    }

            //    allList.Add(newOne);
            //}

            //allList = allList.OrderBy(m => m.SysPowerID).ToList();

            #endregion

            CacheHelper.SetRelativeCache(cacheKey, allList);
            return allList;
        }

        /// <summary>
        /// 清除权限缓存
        /// </summary>
        public static void ClearCacheAndReload(bool isReload = true)
        {
            lock (Sync)
            {
                CacheHelper.RemoveCache(cacheKey);
                if (isReload)
                {
                    using var db = Db;
                    GetAllSysPower(db);
                }
            }
        }

        //public static List<SysPower> AllSysPowerClone()
        //{
        //    using var db = Db;
        //    return AllSysPowerClone(db);
        //}

        /// <summary>
        /// 全Copy
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        internal static List<SysPower> AllSysPowerClone(DbEntities db)
        {
            lock (Sync)
            {
                var allList = GetAllSysPower(db);
                List<SysPower> rightsList = new List<SysPower>();
                foreach (var item in allList)
                {
                    SysPower sr = new SysPower();
                    sr.ExCopyFrom(item);
                    sr.SysPowerID = item.SysPowerID;
                    sr.SonList = null;
                    sr.Parent = null;
                    sr.SonList = new List<SysPower>();

                    rightsList.Add(sr);
                }

                DealRelationToCurrent(rightsList);
                return rightsList;
            }
        }

        private static void DealRelationToCurrent(List<SysPower> rightsList)
        {
            foreach (var item in rightsList)
            {
                if (item.Parent == null)
                {
                    item.Parent = rightsList.FirstOrDefault(m => m.SysPowerID == item.ParentID);
                }
            }
        }

        /// <summary>
        /// 得到权限集合
        /// </summary>
        /// <param name="db"></param>
        /// <param name="rightsIDList"></param>
        /// <param name="withRelation">带上关系</param>
        /// <returns></returns>
        private List<SysPower> GetAllShowRights(DbEntities db, List<int> rightsIDList = null, bool withRelation = false)
        {
            List<SysPower> allList = AllSysPowerClone(db);
            List<SysPower> resultList;
            if (rightsIDList != null)
            {
                resultList = allList.Where(m => rightsIDList.Contains(m.SysPowerID)).ToList();

                //补全没有的rightsid  主要就是分类那一个级别没有
                var addSmallTop = new List<SysPower>();
                foreach (var item in resultList)
                {
                    if (item.ParentID == null) continue;
                    if (resultList.All(m => m.SysPowerID != item.ParentID.Value))
                    {
                        var smallTop = allList.FirstOrDefault(m => m.SysPowerID == item.ParentID.Value);
                        if (smallTop == null) continue;
                        if (addSmallTop.All(m => m.SysPowerID != smallTop.SysPowerID)) addSmallTop.Add(smallTop);
                    }
                }
                resultList.AddRange(addSmallTop);
            }
            else
            {
                resultList = allList;
            }
            if (withRelation == false)
            {
                return resultList;
            }

            List<SysPower> top = DealRelation(resultList);

            //if (withSmallTop == false)
            //{
            //    foreach (SysPower topItem in top)
            //    {
            //        var itemTempList = new List<SysPower>();
            //        foreach (var sonTopItem in topItem.SonList)
            //        {
            //            foreach (var item in sonTopItem.SonList)
            //            {
            //                item.Parent = topItem;

            //                itemTempList.Add(item);
            //            }
            //        }
            //        topItem.SonList = itemTempList;
            //    }
            //}
            return top;
        }

        /// <summary>
        /// 加上关系,只返回top的
        /// </summary>
        /// <param name="resultList"></param>
        private static List<SysPower> DealRelation(List<SysPower> resultList)
        {
            List<SysPower> r = new List<SysPower>();
            List<SysPower> top = resultList.Where(m => m.ParentID == null).ToList();
            foreach (SysPower topItem in top)
            {
                AllSonList(resultList, topItem);
            }
            r.AddRange(top);
            return r;
        }

        /// <summary>
        /// 所有菜单
        /// </summary>
        /// <param name="rightsIDList"></param>
        /// <param name="onlyMenu"></param>
        /// <returns></returns>
        public List<MenuClass> GetAllMenu(List<int> rightsIDList = null, bool onlyMenu = true)
        {
            using (var db = Db)
            {
                return GetAllMenu(db, rightsIDList, onlyMenu);
            }
        }

        /// <summary>
        /// 菜单列表
        /// </summary>
        /// <param name="db"></param>
        /// <param name="rightsIDList"></param>
        /// <param name="onlyMenu"></param>
        /// <returns></returns>
        internal List<MenuClass> GetAllMenu(DbEntities db, List<int> rightsIDList = null, bool onlyMenu = true)
        {
            List<SysPower> list = GetAllShowRights(db, rightsIDList, false);
            if (onlyMenu)
            {
                list = list.Where(m => m.EnumPowerType == EnumPowerType.菜单).ToList();
            }

            List<SysPower> top = list.Where(m => m.ParentID == null).ToList();
            List<MenuClass> r = new List<MenuClass>();
            foreach (SysPower topItem in top)
            {
                MenuClass model = new MenuClass();
                model.id = topItem.SysPowerID.ToString();
                model.rightsId = topItem.SysPowerID;
                model.name = topItem.SysPowerName;
                model.url = string.IsNullOrEmpty(topItem.SysPowerValue) ? string.Empty : topItem.SysPowerValue;

                var children = AllSonList(list, topItem);
                model.children.AddRange(children);

                r.Add(model);
            }
            List<MenuClass> resultMenuClass = r.Where(m => m.children.Count > 0).ToList();
            return resultMenuClass;
        }

        private static List<MenuClass> AllSonList(List<SysPower> list, SysPower topItem)
        {
            List<MenuClass> r = new List<MenuClass>();
            var sonList = list.Where(m => m.ParentID == topItem.SysPowerID).ToList();
            foreach (SysPower son in sonList)
            {
                MenuClass model = new MenuClass();
                model.id = son.SysPowerID.ToString();
                model.rightsId = son.SysPowerID;
                model.name = son.SysPowerName;
                model.url = string.IsNullOrEmpty(son.SysPowerValue) ? string.Empty : son.SysPowerValue;

                var children = AllSonList(list, son);
                model.children.AddRange(children);

                r.Add(model);
            }
            return r;
        }

        public class MenuClass
        {
            public string id { get; set; }

            public string name { get; set; }

            public int rightsId { get; set; }

            public string url { get; set; } = string.Empty;

            public List<MenuClass> children { get; set; } = new List<MenuClass>();
        }

        #endregion

        #region 初始化权限

        #region 导入权限

        /// <summary>
        /// 导入权限
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public AjaxResult<dynamic> InitPower(IFormCollection form)
        {
            var r = new AjaxResult<dynamic>();
            string base64 = form["file"];
            if (string.IsNullOrEmpty(base64))
            {
                r.Message = LanguageHelper.GetString<SysPower>("NoFile");
                return r;
            }

            string fileName = Base64Helper.SaveFileFromBase64(base64, null, false);
            fileName = Base64Helper.GetFullName(fileName);
            if (string.IsNullOrEmpty(fileName) || System.IO.File.Exists(fileName) == false)
            {
                r.Message = LanguageHelper.GetString<SysPower>("FileError");
                return r;
            }
            var list = GetAllSysPowerFromExcel(fileName, out string error);
            if (!string.IsNullOrEmpty(error))
            {
                r.Message = error;
                return r;
            }

            list = RemoveRelation(list);
            //根据数据来 加入客户信息
            int addCount = 0;
            using (DbEntities db = DbEntitiesHelper.GetDbEntities(true))
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        db.Database.ExExecuteSqlCommand($"delete from {nameof(SysPower)}");
                        db.SysPower.AddRange(list);
                        db.SaveChanges();
                        addCount = list.Count;

                        //list重新写入最大权限
                        var role = db.SysRolePost.FirstOrDefault(); //第一个角色最大权限
                        if (role == null)
                        {
                            r.Message = LanguageHelper.GetString<SysPower>("NoRole");
                            return r;
                        }
                        List<SysRolePostPowerRelation> roleRights = list.Select(m => new SysRolePostPowerRelation()
                        {
                            SysRolePostID = role.SysRolePostID,
                            SysPowerID = m.SysPowerID,
                            CreateDate = DateTime.Now,
                            CreateSysEmployeeID = CurrentEmployee.SysEmployeeID
                        }).ToList();

                        //var replaceShowRights = db.SysRolePostPowerRelationReplace.ToList();
                        //var addReplace = replaceShowRights.Where(m => roleRights.All(n => n.SysPowerID != m.SysPowerID)).Select(n => new SysRolePostPowerRelation()
                        //{
                        //    SysRolePostID = role.SysRolePostID,
                        //    SysPowerID = n.SysPowerID
                        //}).ToList();
                        //roleRights.AddRange(addReplace);

                        db.Database.ExExecuteSqlCommand($"delete from {nameof(SysRolePostPowerRelation)} where SysRolePostID={role.SysRolePostID}");
                        db.SysRolePostPowerRelation.AddRange(roleRights);
                        db.SaveChanges();
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        e.ExLogError("权限初始化事务报错");
                        tran.Rollback();
                        r.Message = string.Format(LanguageHelper.Fail1, e.Message);
                        return r;
                    }
                }
                SysRolePostBll.ClearCacheAndReload();
                //System.Web.HttpContext.Current.Session.Clear();
            }

            r.Message = LanguageHelper.GetString<SysPower>("OpSuccess", addCount);
            r.Success = true;
            return r;
        }

        /// <summary>
        /// 去除关系
        /// </summary>
        /// <param name="relationList"></param>
        /// <returns></returns>
        private static List<SysPower> RemoveRelation(List<SysPower> relationList)
        {
            List<SysPower> r = new List<SysPower>();
            foreach (SysPower item in relationList)
            {
                r.Add(item);
                if (item.SonList != null && item.SonList.Count > 0)
                {
                    var sonList = RemoveRelation(item.SonList);
                    r.AddRange(sonList);
                }

                item.SonList = null;
                item.Parent = null;
            }

            return r;
        }

        #endregion

        #region 得到excel权限集合

        private static bool IsNullOrEmpty(object o)
        {
            if (o == null || o == DBNull.Value) return true;
            if (string.IsNullOrEmpty(o.ToString())) return true;
            return false;
        }

        /// <summary>
        /// 得到权限集合
        /// </summary>
        /// <param name="fileFullName"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        private List<SysPower> GetAllSysPowerFromExcel(string fileFullName, out string error)
        {
            //1.从EXCELL中读取数据
            var dt = NPOIHelper.ExcelToDataTable(fileFullName);
            try
            {
                System.IO.File.Delete(fileFullName);
            }
            catch
            {
            }
            //找出重复的
            var rows = dt.Rows.Cast<DataRow>();
            var gb = rows.Where(m => IsNullOrEmpty(m["权限ID"]) == false).GroupBy(m => m["权限ID"]);
            var tempGb = gb.Where(m => m.Count() > 1);
            if (tempGb.Any())
            {
                error = LanguageHelper.GetString<SysPower>("RepeatPowerID", tempGb.FirstOrDefault().Key);
                return null;
            }

            var tempList = new List<string>();//几大SysPowerID的值
            var tempNames = new List<string>()
            {
                "模块ID", "1级菜单ID", "权限ID" //, "2级菜单ID" 二级菜单不能合并的,必须拆开,所以不验证重复
            };
            foreach (var item in tempNames)
            {
                var temp1 = rows.Where(m => IsNullOrEmpty(m[item]) == false).Select(m => m[item].ToString()).ToList();
                tempList.AddRange(temp1);
            }

            tempList = tempList.Where(m => !string.IsNullOrEmpty(m)).ToList();
            var tempRepeat = tempList.GroupBy(m => m).Where(m => m.Count() > 1);
            if (tempRepeat.Any())
            {
                error = LanguageHelper.GetString<SysPower>("RepeatPowerID", tempRepeat.FirstOrDefault().Key + "!");
                return null;
            }

            //2.加载出所有的SysPower和ShowRights
            List<SysPower> top = new List<SysPower>(); //模块
            List<SysPower> first = new List<SysPower>(); //1级菜单
            List<SysPower> second = new List<SysPower>(); //2级菜单
            List<SysPower> last = new List<SysPower>(); //功能

            #region 读取excel数据

            foreach (DataRow item in dt.Rows)
            {
                int topInt = IsNullOrEmpty(item["模块ID"])
                    ? top[top.Count - 1].SysPowerID
                    : Convert.ToInt32(item["模块ID"]);
                string topName = IsNullOrEmpty(item["模块"])
                    ? (top.Count > 0 ? top[top.Count - 1].SysPowerName : null)
                    : Convert.ToString(item["模块"]).Trim();
                string topPath = IsNullOrEmpty(item["模块路径"])
                    ? (top.Count > 0 ? top[top.Count - 1].WebPath : null)
                    : Convert.ToString(item["模块路径"]).Trim();
                //Json不需要上一个的,不需要合并判断
                string topJson = IsNullOrEmpty(item["模块页面Json"])
                    ? null
                    : Convert.ToString(item["模块页面Json"]).Trim();
                int? firstInt = IsNullOrEmpty(item["1级菜单ID"])
                        ? (first.Count > 0 ? (int?)first[first.Count - 1].SysPowerID : null)
                        : Convert.ToInt32(item["1级菜单ID"]);
                string firstName = IsNullOrEmpty(item["1级菜单ID"])
                    ? (first.Count > 0 ? first[first.Count - 1].SysPowerName : null)
                    : Convert.ToString(item["1级菜单"]).Trim();
                string firstPath = IsNullOrEmpty(item["1级菜单路径"])
                    ? (first.Count > 0 ? first[first.Count - 1].WebPath : null)
                    : Convert.ToString(item["1级菜单路径"]).Trim();

                string firstJson = IsNullOrEmpty(item["1级菜单Json"])
                    ? null
                    : Convert.ToString(item["1级菜单Json"]).Trim();

                //int? secondInt = IsNullOrEmpty(item["2级菜单ID"])
                //    ? (second.Count > 0 ? (int?)second[second.Count - 1].SysPowerID : null)
                //    : (int?)Convert.ToInt32(item["2级菜单ID"]);
                //string secondName = IsNullOrEmpty(item["2级菜单"])
                //    ? (second.Count > 0 ? second[second.Count - 1].SysPowerName : null)
                //    : Convert.ToString(item["2级菜单"]).Trim();
                //string secondPath = IsNullOrEmpty(item["2级菜单路径"])
                //    ? (second.Count > 0 ? second[second.Count - 1].WebPath : null)
                //    : Convert.ToString(item["2级菜单路径"]).Trim();
                //string secondJson = IsNullOrEmpty(item["2级菜单Json"])
                //    ? (second.Count > 0 ? second[second.Count - 1].Json : null)
                //    : Convert.ToString(item["2级菜单Json"]).Trim();
                //二级菜单的excel不能合并,其它合并与否都无所谓
                int? secondInt = IsNullOrEmpty(item["2级菜单ID"]) ? null : (int?)Convert.ToInt32(item["2级菜单ID"]);
                string secondName = Convert.ToString(item["2级菜单"]).Trim();
                string secondPath = Convert.ToString(item["2级菜单路径"]).Trim();
                string secondJson = Convert.ToString(item["2级菜单Json"]).Trim();

                int? lastInt = IsNullOrEmpty(item["权限ID"])
                    ? (int?)null
                    : (int?)Convert.ToInt32(item["权限ID"]);
                string lastName = Convert.ToString(item["功能"]).Trim();
                bool isInOp = Convert.ToString(item["操作列里"]).ExToBool();
                bool isDel = Convert.ToString(item["是否删除"]).ExToBool();
                string remark = Convert.ToString(item["相关URL链接"]).Trim();
                string remark2 = Convert.ToString(item["相关URL链接2"]).Trim();
                if (firstPath == "null" || firstPath == "empty")
                {
                    //firstPath = Base64Helper.Space;
                    if (top.All(m => m.SysPowerID != topInt)) //没有模块ID,则加对象
                    {
                        SysPower sr = new SysPower
                        {
                            SysPowerID = topInt,
                            SysPowerName = topName,
                            SonList = new List<SysPower>(),
                            EnumPowerType = EnumPowerType.特殊权限,
                            IsDel = isDel,

                            Json = null,
                            WebPath = null,
                            IsInOp = false,
                            OrderID = topInt,

                            ParentID = null,
                            SysPowerValue = null,
                            SysPowerValue2 = null,
                            Parent = null,
                            Remark = null
                        };
                        top.Add(sr);
                    }
                }
                if (top.All(m => m.SysPowerID != topInt)) //没有模块ID,则加对象
                {
                    SysPower sr = new SysPower
                    {
                        SysPowerID = topInt,
                        SysPowerName = topName,
                        SonList = new List<SysPower>(),
                        EnumPowerType = EnumPowerType.菜单,
                        IsDel = isDel,

                        Json = topJson,
                        WebPath = topPath,
                        IsInOp = false,
                        OrderID = topInt,

                        ParentID = null,
                        SysPowerValue = null,
                        SysPowerValue2 = null,
                        Parent = null,
                        Remark = null
                    };
                    top.Add(sr);
                }
                SysPower firstSr = first.FirstOrDefault(m => m.SysPowerID == firstInt);
                if (firstSr == null && firstInt != null) //没有模块ID,则加对象
                {
                    SysPower sr = new SysPower
                    {
                        SysPowerID = firstInt.Value,
                        SysPowerName = firstName,
                        SonList = new List<SysPower>(),
                        EnumPowerType = EnumPowerType.菜单,
                        IsDel = isDel,

                        Json = firstJson,
                        WebPath = firstPath,
                        IsInOp = false,
                        OrderID = firstInt.Value,
                        ParentID = topInt,
                        SysPowerValue = null
                    };
                    first.Add(sr);
                    firstSr = sr;
                }

                SysPower secondSr = null;
                if (secondInt != null) //没有模块ID,则加对象
                {
                    secondSr = second.FirstOrDefault(m => m.SysPowerID == secondInt);
                    if (secondSr == null)
                    {
                        SysPower sr = new SysPower
                        {
                            SysPowerID = secondInt.Value,
                            SysPowerName = secondName,
                            SonList = new List<SysPower>(),
                            EnumPowerType = EnumPowerType.菜单,
                            IsDel = isDel,
                            ParentID = firstInt,
                            SysPowerValue = null,

                            Json = secondJson,
                            WebPath = secondPath,
                            IsInOp = false,
                            OrderID = secondInt.Value
                        };

                        secondSr = sr;
                        second.Add(sr);
                    }
                }

                if (!string.IsNullOrEmpty(firstPath))
                {
                    if (secondSr != null) //有二级,则是二级的 SysPower,没有,则是一级的SysPower
                    {
                        //firstSr.SonList = new List<SysPower>();
                        //SysPower mb = new SysPower();
                        //mb.SysPowerName = firstSr.SysPowerName;
                        //mb.SysPowerID = firstSr.SysPowerID;
                        //mb.ParentID = firstSr.ParentID;
                        //mb.EnumPowerType = EnumPowerType.菜单;
                        //mb.SysPowerValue = menu;
                        //mb.IsDel = isDel; 
                        //firstSr.SonList.Add(mb); 
                        //secondSr.SonList = new List<SysPower>();
                        //SysPower mb2 = new SysPower();
                        //mb2.SysPowerName = secondSr.SysPowerName;
                        //mb2.ParentID = secondSr.ParentID;
                        //mb2.EnumPowerType = EnumPowerType.菜单;
                        //mb2.IsDel = isDel;
                        //mb2.SysPowerID = secondSr.SysPowerID;
                        //mb2.SysPowerValue = menu;
                        //secondSr.SonList.Add(mb2);
                    }
                    else
                    {
                        if (firstSr != null)
                        {
                            //firstSr.SonList = new List<SysPower>();
                            //SysPower mb = new SysPower();
                            //mb.SysPowerName = firstSr.SysPowerName;
                            //mb.SysPowerID = firstSr.SysPowerID;
                            //mb.ParentID = firstSr.ParentID;
                            //mb.EnumPowerType = EnumPowerType.菜单;
                            //mb.SysPowerValue = menu;
                            //mb.IsDel = isDel;
                            //firstSr.SonList.Add(mb);
                        }
                    }
                }

                //最底层的
                int? parentID = secondInt ?? firstInt;
                EnumPowerType enumPowerType = EnumPowerType.按钮;
                if (parentID == null)
                {
                    parentID = topInt;
                    enumPowerType = EnumPowerType.特殊权限;
                }
                SysPower lastSysPower = new SysPower
                {
                    SysPowerID = lastInt ?? 0,
                    SysPowerName = lastName,
                    SonList = new List<SysPower>(),
                    EnumPowerType = enumPowerType,
                    IsDel = isDel,
                    ParentID = parentID,
                    SysPowerValue = remark,
                    SysPowerValue2 = remark2,
                    WebPath = null,
                    IsInOp = isInOp
                };
                last.Add(lastSysPower);
            }

            #endregion

            //3.建立关系

            #region 建立关系

            foreach (SysPower lastItem in last)
            {
                SysPower secondItem = second.FirstOrDefault(m => m.SysPowerID == lastItem.ParentID);

                SysPower firstItem = null;
                if (secondItem != null)
                {
                    lastItem.Parent = secondItem;
                    secondItem.SonList.Add(lastItem);

                    firstItem = first.FirstOrDefault(m => m.SysPowerID == secondItem.ParentID);
                    if (firstItem == null) continue;
                    if (firstItem.SonList.All(m => m.SysPowerID != secondItem.SysPowerID))
                    {
                        firstItem.SonList.Add(secondItem);
                    }

                    secondItem.Parent = firstItem;
                }
                else
                {
                    var specialTop = top.FirstOrDefault(m => m.SysPowerID == lastItem.ParentID);
                    if (specialTop != null) //是否是特殊权限的
                    {
                        specialTop.SonList.Add(lastItem);
                        lastItem.Parent = specialTop;
                        BuildSysPowerID(lastItem);
                        continue; //特殊权限,直接是最顶级,不需要后续操作
                    }

                    firstItem = first.FirstOrDefault(m => m.SysPowerID == lastItem.ParentID);
                    if (firstItem == null) continue;
                    lastItem.Parent = firstItem;
                    firstItem.SonList.Add(lastItem);
                }

                SysPower topItem = top.FirstOrDefault(m => m.SysPowerID == firstItem.ParentID);
                if (topItem == null) continue;
                if (topItem.SonList.All(m => m.SysPowerID != firstItem.SysPowerID))
                {
                    firstItem.Parent = topItem;
                    topItem.SonList.Add(firstItem);
                }

                firstItem.Parent = topItem;

                BuildSysPowerID(lastItem);
            }

            #endregion

            error = null;
            return top;
        }

        private static void BuildSysPowerID(SysPower lastItem)
        {
            var parent = lastItem.Parent;
            if (lastItem.SysPowerID == 0 && parent != null)
            {
                lastItem.SysPowerID = parent.SysPowerID + (parent.SonList.IndexOf(lastItem) + 1);
            }
        }

        #endregion

        #endregion

        #region 检查数据库

        /// <summary>
        /// 检查数据库
        /// </summary>
        /// <returns></returns>
        public AjaxResult<dynamic> CheckDb()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var r = new AjaxResult<dynamic>();
            var type = typeof(DbEntities);
            var ps = type.GetProperties();
            var listDbTableName = new List<string>();
            using var db = Db;
            MethodInfo dbSetMethod = type.GetMethod(nameof(db.Set), new Type[] { });
            //this System.Linq.IQueryable<TSource> source, int count;
            MethodInfo takeMethodTemp = typeof(System.Linq.Queryable).GetMethod(nameof(System.Linq.Queryable.Take), new Type[] { typeof(IQueryable<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(int) });
            MethodInfo toListMethodTemp = typeof(System.Linq.Enumerable).GetMethod(nameof(System.Linq.Enumerable.ToList));
            foreach (var p in ps)
            {
                if (p.PropertyType.IsGenericType == false || p.PropertyType.GenericTypeArguments.Length == 0) continue;
                Type dbTblType = p.PropertyType.GenericTypeArguments[0];
                Type dbSetType = typeof(DbSet<>).MakeGenericType(dbTblType);
                if (p.PropertyType != dbSetType) continue;
                try
                {
                    //示例 Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[YBX3.Model.SysLog]
                    //DbSet<SysLog> setTemp = db.Set<SysLog>();
                    //IQueryable<SysLog> listTemp2Temp = System.Linq.Queryable.Take(setTemp, 1);
                    //List<SysLog> listTemp2 = System.Linq.Enumerable.ToList(listTemp2Temp);
                    //List<SysLog> listTemp = setTemp.Take(1).ToList();

                    //反射
                    MethodInfo dbSetT = dbSetMethod.MakeGenericMethod(dbTblType);
                    object dbSetObj = dbSetT.Invoke(db, null);
                    MethodInfo takeMethod = takeMethodTemp.MakeGenericMethod(dbTblType);
                    object take1 = takeMethod.Invoke(null, new object[] { dbSetObj, 1 });
                    MethodInfo toListMethod = toListMethodTemp.MakeGenericMethod(dbTblType);
                    object list = toListMethod.Invoke(null, new object[] { take1 });
                    listDbTableName.Add(dbTblType.Name);
                    continue;
                }
                catch (Exception e)
                {
                    string tblName = p.Name;
                    //e.ExLogError($"检查数据库报错:表名:{tblName}");
                    r.Message = string.Format(LanguageHelper.Fail1, $"表名:{tblName};" + e.ExFullString());
                    return r;
                }
            }
            //没有计入的数据库表
            List<string> allTableNameList = db.Database.ExSqlQuery<TableName>("select name from dbo.sysobjects where Type='U'").ToList().Select(m => m.name).ToList();
            List<string> listNotIn = allTableNameList.ExNotContains(listDbTableName);
            sw.Stop();
            //string.Format(LanguageHelper.Fail1, "");
            r.Message = string.Format(LanguageHelper.Success1, $"耗时:{sw.ElapsedMilliseconds}毫秒;检测了{listDbTableName.Count}张表!其中表{listNotIn.Count}张表没有进入EF管理({listNotIn.ExJoin()});所有EF的表名:{listDbTableName.ExJoin()}");
            r.Success = true;
            return r;
        }

        private class TableName
        {
            public string name { get; set; }
        }

        #endregion
    }
}
